package templates;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import jebl.evolution.graphs.Node;
import jebl.evolution.trees.RootedTree;
import structure.Coordinates;
import utils.ThreadLocalSpreadDate;
import utils.Utils;
public class AnalyzeTree implements Runnable {
private static final int DaysInYear = 365;
private RootedTree currentTree;
private String precisionString;
private String coordinatesName;
private String rateString;
private double timescaler;
private double[] sliceHeights;
private ThreadLocalSpreadDate mrsd;
private ConcurrentMap<Double, List<Coordinates>> slicesMap;
private boolean useTrueNoise;
public AnalyzeTree(RootedTree currentTree, String precisionString,
String coordinatesName, String rateString, double[] sliceHeights,
double timescaler, ThreadLocalSpreadDate mrsd,
ConcurrentMap<Double, List<Coordinates>> slicesMap,
boolean useTrueNoise) {
this.currentTree = currentTree;
this.precisionString = precisionString;
this.coordinatesName = coordinatesName;
this.rateString = rateString;
this.sliceHeights = sliceHeights;
this.timescaler = timescaler;
this.mrsd = mrsd;
this.slicesMap = slicesMap;
this.useTrueNoise = useTrueNoise;
}// END: Constructor
public void run() throws ConcurrentModificationException {
try {
// attributes parsed once per tree
double currentTreeNormalization = Utils.getTreeLength(currentTree,
currentTree.getRootNode());
double[] precisionArray = Utils.getTreeDoubleArrayAttribute(
currentTree, precisionString);
for (Node node : currentTree.getNodes()) {
if (!currentTree.isRoot(node)) {
// attributes parsed once per node
Node parentNode = currentTree.getParent(node);
double nodeHeight = Utils.getNodeHeight(currentTree, node);
double parentHeight = Utils.getNodeHeight(currentTree,
parentNode);
double[] location = Utils.getDoubleArrayNodeAttribute(node,
coordinatesName);
double[] parentLocation = Utils
.getDoubleArrayNodeAttribute(parentNode,
coordinatesName);
double rate = Utils
.getDoubleNodeAttribute(node, rateString);
for (int i = 0; i < sliceHeights.length; i++) {
double sliceHeight = sliceHeights[i];
if (nodeHeight < sliceHeight && sliceHeight <= parentHeight) {
double[] imputedLocation = Utils.imputeValue(location,
parentLocation, sliceHeight, nodeHeight,
parentHeight, rate, useTrueNoise,
currentTreeNormalization, precisionArray);
// calculate key
int days = (int) (sliceHeight * DaysInYear * timescaler);
double sliceTime = mrsd.minus(days);
// grow map entry if key exists
if (slicesMap.containsKey(sliceTime)) {
slicesMap.get(sliceTime).add(
new Coordinates(imputedLocation[1], // longitude
imputedLocation[0], // latitude
0.0 // altitude
));
// start new entry if no such key in the map
} else {
List<Coordinates> coords = new ArrayList<Coordinates>();
coords.add(new Coordinates(imputedLocation[1], // longitude
imputedLocation[0], // latitude
0.0 // altitude
));
slicesMap.put(sliceTime, coords);
}// END: key check
}// END: sliceTime check
}// END: numberOfIntervals loop
}// END: root node check
}// END: node loop
} catch (Exception e) {
e.printStackTrace();
}// END: try-caych block
}// END: run
}// END: AnalyzeTree